#ifndef GAME_ANIMATION_SKY_DOME_CLOUD_SHADER_H
#define GAME_ANIMATION_SKY_DOME_CLOUD_SHADER_H
//
// Game Animation.
// Copyright (C) 2007 Department of Computer Science, University of Copenhagen
//
#include <animation/configuration.h>

#include <OpenTissue/gpu/cg/cg_program.h>
#include <OpenTissue/gpu/image/image.h>
#include <OpenTissue/gpu/image/io/image_read.h>
#include <OpenTissue/gpu/image/io/image_write.h>
#include <OpenTissue/gpu/texture/texture_texture2D.h>
#include <OpenTissue/gpu/image/image_make_noise.h>
#include <OpenTissue/gpu/image/image_alpha_modulation.h>

namespace animation
{

  /**
   * The Sky Shader Class.
   * Sets up rendering before drawing sky dome geometry.
   */
  class SkyDomeCloudShader
  {
  protected:

    OpenTissue::cg::Program                                      m_vertex_program;
    OpenTissue::cg::Program                                      m_fragment_program;
    boost::shared_ptr<OpenTissue::image::Image<unsigned char> >  m_noise_image;
    OpenTissue::texture::texture2D_pointer                       m_noise_texture;
  public:

    /**
     * Pre-render
     *
     * @param lower_x    The minimum x-coordinate of the AABB enclosing the sky dome (i.e. the sky sphere).
     * @param lower_y    The minimum y-coordinate of the AABB enclosing the sky dome (i.e. the sky sphere).
     * @param lower_z    The minimum z-coordinate of the AABB enclosing the sky dome (i.e. the sky sphere).
     * @param width      The width of the enclosing AABB.
     * @param height     The height of the enclosing AABB.
     * @param depth      The depth length of the enclosing AABB.
     */
    bool pre_render (
		bool reload
	  , float time
      , float lower_x
      , float lower_y
      , float lower_z
      , float width
      , float height
      , float depth
	  ,	float light_x,float light_y,float light_z
	  , float intensity
	  , float fog_density
	  , float fog_color_r, float fog_color_g, float fog_color_b
	  , bool flipped
      ){
        //--- Setup openGL state
		  if(flipped==false){
			  glCullFace(GL_FRONT);
			  glEnable(GL_CULL_FACE);
		  }
        glDepthMask(0);

		
		//--- Load textures if they are not allready loaded
		if(!m_noise_image){
			m_noise_image.reset( new OpenTissue::image::Image<unsigned char>() );
			OpenTissue::image::read(demo_path + "TheSwampThing2008/data/cloud_noise.png",*m_noise_image);
			m_noise_texture = m_noise_image->create_texture(GL_RGBA);
			m_noise_texture->set_repeating(true);
			m_noise_texture->set_mipmapping(true);
		}

      //--- Load vertex program, note that cg-program path is currently hardcoded, a
      //--- more sensible solution would be
      //---
      //---  std::string filename = get_environment_variable("OPENTISSUE") + .... + "vp_grass.cg";
      //---
	  bool no_shade=false;
      if(!m_vertex_program.is_program_loaded()||reload)
		  if(!m_vertex_program.load_from_file(OpenTissue::cg::Program::vertex_program,demo_path + "../animation/shader/skydome/cloud_vp.cg")){
			  return false;
		  }

	  if(!m_fragment_program.is_program_loaded()||reload){
		if(!m_fragment_program.load_from_file(OpenTissue::cg::Program::fragment_program,demo_path + "../animation/shader/skydome/cloud_fp.cg")){
			return false;
	 	}
	  }
	  m_vertex_program.set_float_param("params",               width, height, depth, time);
	  m_vertex_program.set_float_param("offset",              lower_x,  lower_y,  lower_z);
	  m_vertex_program.set_float_param("light_vec",light_x,light_y,light_z);
	  m_vertex_program.set_float_param("intensity",intensity);
	  m_vertex_program.set_modelview_projection_matrix();
	  //--- load fragment program
	  m_fragment_program.set_input_texture("cloud_noise",m_noise_texture);
	  m_fragment_program.set_float_param( "fog_density",  fog_density  );
	  m_fragment_program.set_float_param( "fog_color",  fog_color_r,fog_color_g,fog_color_b);

	  m_fragment_program.enable();
	  m_vertex_program.enable();
	  return true;
	}


    void post_render()
    {
      glDepthMask(1);
      glCullFace(GL_BACK);
      glDisable(GL_CULL_FACE);
      m_fragment_program.disable();
      m_vertex_program.disable();
    }
  };

} // namespace animation

// GAME_ANIMATION_SKY_SHADER_H
#endif
